<!-- 参数 》 多选下拉框 -->

<template>
  <div v-bind="paramProps">
    <label v-if="label" v-bind="labelProps">{{ label }}</label>

    <el-select
      v-model="model"
      v-bind="commonProps"
      :placeholder="CORE.isEmpty(model) ? placeholder : ''"
      :popperClass="popperClass"
      :filterable="!noSearch"
      :multiple-limit="limit"
      collapse-tags
      multiple
      @change="emitChange"
    >
      <el-option
        v-for="(item, i) in selectData"
        :key="`${item[0]}-${i}`"
        :class="getHideClass(item)"
        :value="item[0]"
        :label="item[1]"
        :disabled="getDisabled(item)"
      >
        <div class="CoreWeb-option">
          <slot name="item" :item="item">
            <div>{{ item[1] }}</div>
            <div v-if="showRight" class="CoreWeb-option-right">{{ item[rightIndex] }}</div>
          </slot>
        </div>
      </el-option>
    </el-select>
  </div>
</template>

<script>
// ============================== 导入依赖 ============================== //

import CORE from '@/CORE'
import mixParam from '../mixParam'
import FormSelectMulti from '../../form/FormSelectMulti'

const name = 'ParamSelectMulti'

// ============================== 导出组件 ============================== //

export default {
  /**
   * 名称定义 (实际使用名称)
   */
  name,

  /**
   * 混入列表 (配置选项合并)
   */
  mixins: [mixParam],

  /**
   * 属性注册 (抽取以便查阅)
   */
  props: CORE.WEB[name],

  /**
   * 状态数据 (函数返回对象)
   */
  data() {
    return FormSelectMulti.data()
  },

  /**
   * 计算属性 (慎用箭头函数)
   */
  computed: FormSelectMulti.computed,

  /**
   * 本地方法 (轻量重要在前)
   */
  methods: {
    /**
     * 是否不等 (可覆盖)
     */
    isDiff() {
      const { obj, prop, join, model, dict } = this
      const v = obj[prop]
      const values = join && CORE.isString(v) ? v ? v.split(',') : [] : v

      // 非数组
      if (!values || !CORE.isArray(values)) return true
      // 有值，但不相等
      if (values.join() !== model.join()) return true
      // 相等
      return values.some(value => !(dict || []).find(([id]) => value === id))
    },

    /**
     * 设置内部绑定值 (可覆盖)
     */
    setModel() {
      const { obj, prop, join, allIdList } = this
      const v = obj[prop]
      const values = join && CORE.isString(v) ? v ? v.split(',') : [] : v

      // 非数组
      if (!values || !CORE.isArray(values)) this.model = []
      // 有值
      else this.model = values.filter((value) => allIdList.includes(value))
    },

    /**
     * 获取最终回传值 (可覆盖)
     */
    getValue() {
      const { join, model } = this
      if (join) return model ? model.join() : ''
      return model || []
    },

    /**
     * 是否相等 (可覆盖)
     */
    equals(value) {
      const { obj, prop, join, init, emitChange } = this
      const v = obj[prop]
      const values = join && CORE.isString(v) ? v ? v.split(',') : [] : v
      const model = join ? value ? value.split(',') : [] : value

      // 非数组
      if (!values) return false

      // 无值，但有默认值
      if (!model.length && init.length) {
        this.model = init // 设为默认值
        emitChange() // 重新走提交流程
        return true // 本次不再更新
      }

      // 有值，直接比较
      return values.join() === model.join()
    },

    /**
     * 提交改变 (可覆盖)
     */
    emitChange() {
      const { setAllHalf, getValue, equals, obj, prop, afterEmit } = this

      // 设置全选半选
      setAllHalf()

      // 获取新值
      const value = getValue()

      // 判断改变
      if (equals(value)) return

      // 更新绑定
      this.$set(obj, prop, value)
      this.$emit('change', value)

      // 提交之后
      afterEmit()
    },

    /**
     * 切换全选
     */
    changeAll: FormSelectMulti.methods.changeAll,

    /**
     * 设置全选半选
     */
    setAllHalf: FormSelectMulti.methods.setAllHalf,

    /**
     * 获取隐藏样式类
     */
    getHideClass: FormSelectMulti.methods.getHideClass,

    /**
     * 获取是否禁用
     */
    getDisabled: FormSelectMulti.methods.getDisabled,
  },
}
</script>
